// Auto generated from tools/makeassets.py

static const unsigned char DATA_shaders_atmosphere_glsl[3770] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "\n"
    "uniform highp float u_atm_p[12];\n"
    "uniform highp vec3  u_sun;\n"
    "uniform highp float u_tm[3]; // Tonemapping koefs.\n"
    "\n"
    "varying lowp    vec4        v_color;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "#includes \"projections.glsl\"\n"
    "\n"
    "attribute highp   vec4       a_pos;\n"
    "attribute highp   vec3       a_sky_pos;\n"
    "attribute highp   float      a_luminance;\n"
    "\n"
    "highp float gammaf(highp float c)\n"
    "{\n"
    "    if (c < 0.0031308)\n"
    "      return 19.92 * c;\n"
    "    return 1.055 * pow(c, 1.0 / 2.4) - 0.055;\n"
    "}\n"
    "\n"
    "vec3 xyy_to_srgb(highp vec3 xyy)\n"
    "{\n"
    "    const highp mat3 xyz_to_rgb = mat3(3.2406, -0.9689, 0.0557,\n"
    "                                      -1.5372, 1.8758, -0.2040,\n"
    "                                      -0.4986, 0.0415, 1.0570);\n"
    "    highp vec3 xyz = vec3(xyy[0] * xyy[2] / xyy[1], xyy[2],\n"
    "               (1.0 - xyy[0] - xyy[1]) * xyy[2] / xyy[1]);\n"
    "    highp vec3 srgb = xyz_to_rgb * xyz;\n"
    "    clamp(srgb, 0.0, 1.0);\n"
    "    return srgb;\n"
    "}\n"
    "\n"
    "void main()\n"
    "{\n"
    "    highp vec3 xyy;\n"
    "    highp float cos_gamma, cos_gamma2, gamma, cos_theta;\n"
    "    highp vec3 p = a_sky_pos;\n"
    "\n"
    "    gl_Position = proj(a_pos.xyz);\n"
    "\n"
    "    // First compute the xy color component (chromaticity) from Preetham model\n"
    "    // and re-inject a_luminance for Y component (luminance).\n"
    "    p[2] = abs(p[2]); // Mirror below horizon.\n"
    "    cos_gamma = dot(p, u_sun);\n"
    "    cos_gamma2 = cos_gamma * cos_gamma;\n"
    "    gamma = acos(cos_gamma);\n"
    "    cos_theta = p[2];\n"
    "\n"
    "    xyy.x = ((1. + u_atm_p[0] * exp(u_atm_p[1] / cos_theta)) *\n"
    "             (1. + u_atm_p[2] * exp(u_atm_p[3] * gamma) +\n"
    "              u_atm_p[4] * cos_gamma2)) * u_atm_p[5];\n"
    "    xyy.y = ((1. + u_atm_p[6] * exp(u_atm_p[7] / cos_theta)) *\n"
    "             (1. + u_atm_p[8] * exp(u_atm_p[9] * gamma) +\n"
    "              u_atm_p[10] * cos_gamma2)) * u_atm_p[11];\n"
    "    xyy.z = a_luminance;\n"
    "\n"
    "    // Ad-hoc tuning. Scaling before the blue shift allows to obtain proper\n"
    "    // blueish colors at sun set instead of very red, which is a shortcoming\n"
    "    // of preetham model.\n"
    "    xyy.z *= 0.08;\n"
    "\n"
    "    // Convert this sky luminance/chromaticity into perceived color using model\n"
    "    // from Henrik Wann Jensen (2000)\n"
    "    // We deal with 3 cases:\n"
    "    //  * Y <= 0.01: scotopic vision. Only the eyes' rods see. No colors,\n"
    "    //    everything is converted to night blue (xy = 0.25, 0.25)\n"
    "    //  * Y > 3.981: photopic vision. Only the eyes's cones seew ith full colors\n"
    "    //  * Y > 0.01 and Y <= 3.981: mesopic vision. Rods and cones see in a\n"
    "    //    transition state.\n"
    "    //\n"
    "    // Compute s, ratio between scotopic and photopic vision\n"
    "    highp float op = (log(xyy.z) / log(10.) + 2.) / 2.6;\n"
    "    highp float s = (xyy.z <= 0.01) ? 0.0 : (xyy.z > 3.981) ? 1.0 : op * op * (3. - 2. * op);\n"
    "\n"
    "    // Perform the blue shift on chromaticity\n"
    "    xyy.x = mix(0.25, xyy.x, s);\n"
    "    xyy.y = mix(0.25, xyy.y, s);\n"
    "    // Scale scotopic luminance for scotopic pixels\n"
    "    xyy.z = 0.4468 * (1. - s) * xyy.z + s * xyy.z;\n"
    "\n"
    "    // Apply logarithmic tonemapping on luminance Y only.\n"
    "    // There is a difference with the code in tonemapper.c (assuming q == 1)\n"
    "    // because we cap the exposure to 1 to avoid saturating the sky.\n"
    "    // This is ad-hoc code to fix rendering issue.\n"
    "    xyy.z = min(0.7, log(1.0 + xyy.z * u_tm[0]) / log(1.0 + u_tm[1] * u_tm[0]) * u_tm[2]);\n"
    "\n"
    "    // Convert xyY to sRGB\n"
    "    highp vec3 rgb = xyy_to_srgb(xyy);\n"
    "\n"
    "    // Apply gamma correction\n"
    "    v_color = vec4(gammaf(rgb.r), gammaf(rgb.g),gammaf(rgb.b), 1.0);\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_FragColor = v_color;\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_atmosphere_glsl, "shaders/atmosphere.glsl", DATA_shaders_atmosphere_glsl, false)

static const unsigned char DATA_shaders_blit_glsl[984] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "uniform mediump vec4        u_color;\n"
    "uniform mediump sampler2D   u_tex;\n"
    "\n"
    "varying highp   vec2        v_tex_pos;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "#ifdef PROJ\n"
    "#includes \"projections.glsl\"\n"
    "#endif\n"
    "\n"
    "attribute highp     vec3    a_pos;\n"
    "attribute mediump   vec2    a_tex_pos;\n"
    "\n"
    "void main()\n"
    "{\n"
    "#ifdef PROJ\n"
    "    gl_Position = proj(a_pos);\n"
    "#else\n"
    "    gl_Position = vec4(a_pos, 1.0);\n"
    "#endif\n"
    "    v_tex_pos = a_tex_pos;\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "void main()\n"
    "{\n"
    "#ifndef TEXTURE_LUMINANCE\n"
    "    gl_FragColor = texture2D(u_tex, v_tex_pos) * u_color;\n"
    "#else\n"
    "    // Luminance mode: the texture only applies to the alpha channel.\n"
    "    gl_FragColor = u_color;\n"
    "    gl_FragColor.a *= texture2D(u_tex, v_tex_pos).r;\n"
    "#endif\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_blit_glsl, "shaders/blit.glsl", DATA_shaders_blit_glsl, false)

static const unsigned char DATA_shaders_fog_glsl[855] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "\n"
    "uniform lowp    vec4        u_color;\n"
    "\n"
    "varying lowp    vec4        v_color;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "#includes \"projections.glsl\"\n"
    "\n"
    "attribute highp   vec4       a_pos;\n"
    "attribute highp   vec3       a_sky_pos;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_Position = proj(a_pos.xyz);\n"
    "    const lowp float height = 0.2;\n"
    "    const lowp float alpha = 0.15;\n"
    "    lowp float d = smoothstep(height, 0.0, abs(a_sky_pos.z));\n"
    "    v_color = u_color;\n"
    "    v_color.a *= alpha * d;\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_FragColor = v_color;\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_fog_glsl, "shaders/fog.glsl", DATA_shaders_fog_glsl, false)

static const unsigned char DATA_shaders_lines_glsl[2117] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "uniform   lowp      vec2    u_win_size;\n"
    "uniform   lowp      float   u_line_width;\n"
    "uniform   lowp      float   u_line_glow;\n"
    "uniform   lowp      vec4    u_color;\n"
    "\n"
    "#ifdef DASH\n"
    "// Dash effect defined as a total length (dash and space, in uv unit),\n"
    "// and the ratio of the dash dot to the length.\n"
    "uniform   lowp      float   u_dash_length;\n"
    "uniform   lowp      float   u_dash_ratio;\n"
    "#endif\n"
    "\n"
    "#ifdef FADE\n"
    "uniform     lowp    float   u_fade_dist_min;\n"
    "uniform     lowp    float   u_fade_dist_max;\n"
    "varying     lowp    float   v_alpha;\n"
    "#endif\n"
    "\n"
    "varying   mediump   vec2    v_uv;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "#includes \"projections.glsl\"\n"
    "\n"
    "attribute highp     vec3    a_pos;\n"
    "attribute highp     vec2    a_wpos;\n"
    "attribute highp     vec2    a_tex_pos;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_Position = proj(a_pos);\n"
    "    gl_Position.xy = (a_wpos / u_win_size - 0.5) * vec2(2.0, -2.0);\n"
    "    gl_Position.xy *= gl_Position.w;\n"
    "    v_uv = a_tex_pos;\n"
    "\n"
    "#ifdef FADE\n"
    "    v_alpha = smoothstep(u_fade_dist_max, u_fade_dist_min, -a_pos.z);\n"
    "#endif\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "void main()\n"
    "{\n"
    "    mediump float dist = abs(v_uv.y); // Distance to line in pixel.\n"
    "    // Use smooth step on 2.4px to emulate an anti-aliased line\n"
    "    mediump float base = smoothstep(u_line_width / 2.0 + 1.2, u_line_width / 2.0 - 1.2, dist);\n"
    "    // Generate a glow with 5px radius\n"
    "    mediump float glow = (1.0 - dist / 5.0) * u_line_glow;\n"
    "    // Only use the most visible of both to avoid changing brightness\n"
    "    gl_FragColor = vec4(u_color.rgb, u_color.a * max(glow, base));\n"
    "\n"
    "#ifdef DASH\n"
    "    lowp float len = u_dash_length;\n"
    "    lowp float r = u_dash_ratio;\n"
    "    gl_FragColor.a *= smoothstep(len / 2.0 * r + 0.01,\n"
    "                                 len / 2.0 * r - 0.01,\n"
    "                                 abs(mod(v_uv.x, len) - len / 2.0));\n"
    "#endif\n"
    "\n"
    "#ifdef FADE\n"
    "    gl_FragColor.a *= v_alpha;\n"
    "#endif\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_lines_glsl, "shaders/lines.glsl", DATA_shaders_lines_glsl, false)

static const unsigned char DATA_shaders_mesh_glsl[588] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "varying   lowp    vec4 v_color;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "#includes \"projections.glsl\"\n"
    "\n"
    "attribute highp   vec3 a_pos;\n"
    "attribute lowp    vec4 a_color;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_Position = proj(a_pos);\n"
    "    v_color = a_color;\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_FragColor = v_color;\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_mesh_glsl, "shaders/mesh.glsl", DATA_shaders_mesh_glsl, false)

static const unsigned char DATA_shaders_planet_glsl[7260] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "#define PI 3.14159265\n"
    "\n"
    "#ifdef GL_ES\n"
    "precision mediump float;\n"
    "#endif\n"
    "\n"
    "uniform lowp    vec4      u_color;\n"
    "uniform mediump sampler2D u_tex;\n"
    "uniform mediump sampler2D u_normal_tex;\n"
    "uniform mediump mat3      u_tex_transf;\n"
    "uniform mediump mat3      u_normal_tex_transf;\n"
    "uniform lowp    vec3      u_light_emit;\n"
    "uniform lowp    float     u_min_brightness;\n"
    "uniform mediump mat4      u_mv;  // Model view matrix.\n"
    "uniform lowp    int       u_has_normal_tex;\n"
    "uniform lowp    int       u_material; // 0: Oren Nayar, 1: generic, 2: ring\n"
    "uniform lowp    int       u_is_moon; // Set to 1 for the Moon only.\n"
    "uniform lowp    float     u_contrast;\n"
    "\n"
    "uniform highp   vec4      u_sun; // Sun pos (xyz) and radius (w).\n"
    "\n"
    "#ifdef HAS_SHADOW\n"
    "// Up to four spheres for illumination ray tracing.\n"
    "uniform mediump sampler2D u_shadow_color_tex; // Used for the Moon.\n"
    "uniform lowp    int       u_shadow_spheres_nb;\n"
    "uniform highp   mat4      u_shadow_spheres;\n"
    "#endif\n"
    "\n"
    "varying highp   vec3 v_mpos;\n"
    "varying mediump vec2 v_tex_pos;\n"
    "varying mediump vec2 v_normal_tex_pos;\n"
    "varying lowp    vec4 v_color;\n"
    "varying highp   vec3 v_normal;\n"
    "varying highp   vec3 v_tangent;\n"
    "varying highp   vec3 v_bitangent;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "#includes \"projections.glsl\"\n"
    "\n"
    "attribute highp   vec3 a_pos;     // View position (with fake scaling).\n"
    "attribute highp   vec3 a_mpos;    // Model position (without fake scaling).\n"
    "attribute mediump vec2 a_tex_pos;\n"
    "attribute lowp    vec3 a_color;\n"
    "attribute highp   vec3 a_normal;\n"
    "attribute highp   vec3 a_tangent;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_Position = proj(a_pos);\n"
    "\n"
    "    v_mpos = a_mpos;\n"
    "    v_tex_pos = (u_tex_transf * vec3(a_tex_pos, 1.0)).xy;\n"
    "    v_normal_tex_pos = (u_normal_tex_transf * vec3(a_tex_pos, 1.0)).xy;\n"
    "    v_color = vec4(a_color, 1.0) * u_color;\n"
    "\n"
    "    v_normal = normalize(a_normal);\n"
    "    v_tangent = normalize(a_tangent);\n"
    "    v_bitangent = normalize(cross(v_normal, v_tangent));\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "float oren_nayar_diffuse(\n"
    "        vec3 lightDirection,\n"
    "        vec3 viewDirection,\n"
    "        vec3 surfaceNormal,\n"
    "        float roughness,\n"
    "        float albedo) {\n"
    "\n"
    "    float r2 = roughness * roughness;\n"
    "    float LdotV = dot(lightDirection, viewDirection);\n"
    "    float NdotL = dot(lightDirection, surfaceNormal);\n"
    "    float NdotV = dot(surfaceNormal, viewDirection);\n"
    "    float NaL = acos(NdotL);\n"
    "    float NaV = acos(NdotV);\n"
    "    float alpha = max(NaV, NaL);\n"
    "    float beta = min(NaV, NaL);\n"
    "    float gamma = dot(viewDirection - surfaceNormal * NdotV,\n"
    "                      lightDirection - surfaceNormal * NdotL);\n"
    "    float A = 1.0 - 0.5 * (r2 / (r2 + 0.33));\n"
    "    float B = 0.45 * r2 / (r2 + 0.09);\n"
    "    float C = sin(alpha) * tan(beta);\n"
    "    float scale = 1.6; // Empirical value!\n"
    "    return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C) * scale;\n"
    "}\n"
    "\n"
    "/*\n"
    " * Compute the illumination if we only consider a single sphere in the scene.\n"
    " * Parameters:\n"
    " *   p       - The surface point where we compute the illumination.\n"
    " *   sphere  - A sphere: xyz -> pos, w -> radius.\n"
    " *   sun_pos - Position of the sun.\n"
    " *   sun_r   - Precomputed sun angular radius from the given point.\n"
    " */\n"
    "float illumination_sphere(highp vec3 p, highp vec4 sphere,\n"
    "                          highp vec3 sun_pos, highp float sun_r)\n"
    "{\n"
    "    // Sphere angular radius as viewed from the point.\n"
    "    highp float sph_r = asin(sphere.w / length(sphere.xyz - p));\n"
    "    // Angle <sun, pos, sphere>\n"
    "    highp float d = acos(min(1.0, dot(normalize(sun_pos - p),\n"
    "                                normalize(sphere.xyz - p))));\n"
    "\n"
    "    // Special case for the moon, to simulate lunar eclipses.\n"
    "    // We assume the only body that can cast shadow on the moon is the Earth.\n"
    "    if (u_is_moon == 1) {\n"
    "        if (d >= sun_r + sph_r) return 1.0; // Outside of shadow.\n"
    "        if (d <= sph_r - sun_r) return d / (sph_r - sun_r) * 0.6; // Umbra.\n"
    "        if (d <= sun_r - sph_r) // Penumbra completely inside.\n"
    "            return 1.0 - sph_r * sph_r / (sun_r * sun_r);\n"
    "        return ((d - abs(sun_r - sph_r)) /\n"
    "                (sun_r + sph_r - abs(sun_r - sph_r))) * 0.4 + 0.6;\n"
    "    }\n"
    "\n"
    "    if (d >= sun_r + sph_r) return 1.0; // Outside of shadow.\n"
    "    if (d <= sph_r - sun_r) return 0.0; // Umbra.\n"
    "    if (d <= sun_r - sph_r) // Penumbra completely inside.\n"
    "        return 1.0 - sph_r * sph_r / (sun_r * sun_r);\n"
    "\n"
    "    // Penumbra partially inside.\n"
    "    // I took this from Stellarium, even though I am not sure how it works.\n"
    "    highp float x = (sun_r * sun_r + d * d - sph_r * sph_r) / (2.0 * d);\n"
    "    highp float alpha = acos(x / sun_r);\n"
    "    highp float beta = acos((d - x) / sph_r);\n"
    "    highp float AR = sun_r * sun_r * (alpha - 0.5 * sin(2.0 * alpha));\n"
    "    highp float Ar = sph_r * sph_r * (beta - 0.5 * sin(2.0 * beta));\n"
    "    highp float AS = sun_r * sun_r * 2.0 * 1.57079633;\n"
    "    return 1.0 - (AR + Ar) / AS;\n"
    "}\n"
    "\n"
    "/*\n"
    " * Compute the illumination at a given point.\n"
    " * Parameters:\n"
    " *   p       - The surface point where we compute the illumination.\n"
    " */\n"
    "float illumination(highp vec3 p)\n"
    "{\n"
    "#ifndef HAS_SHADOW\n"
    "    return 1.0;\n"
    "#else\n"
    "    if (u_shadow_spheres_nb == 0) return 1.0;\n"
    "    mediump float ret = 1.0;\n"
    "    highp float sun_r = asin(u_sun.w / length(u_sun.xyz - p));\n"
    "    for (int i = 0; i < 4; ++i) {\n"
    "        if (u_shadow_spheres_nb > i) {\n"
    "            highp vec4 sphere = u_shadow_spheres[i];\n"
    "            ret = min(ret, illumination_sphere(p, sphere, u_sun.xyz, sun_r));\n"
    "        }\n"
    "    }\n"
    "    return ret;\n"
    "#endif\n"
    "}\n"
    "\n"
    "void main()\n"
    "{\n"
    "    vec3 light_dir = normalize(u_sun.xyz - v_mpos);\n"
    "    // Compute N in view space\n"
    "    vec3 n = v_normal;\n"
    "    if (u_has_normal_tex != 0) {\n"
    "        n = texture2D(u_normal_tex, v_normal_tex_pos).rgb - vec3(0.5, 0.5, 0.0);\n"
    "        // XXX: inverse the Y coordinates, don't know why!\n"
    "        n = +n.x * v_tangent - n.y * v_bitangent + n.z * v_normal;\n"
    "    }\n"
    "    n = normalize(n);\n"
    "    vec4 base_color = texture2D(u_tex, v_tex_pos) * v_color;\n"
    "    vec3 color = (base_color.rgb - 0.5) * u_contrast + 0.5;\n"
    "\n"
    "    if (u_material == 0) { // oren_nayar.\n"
    "        float power = oren_nayar_diffuse(light_dir,\n"
    "                                         normalize(-v_mpos),\n"
    "                                         n,\n"
    "                                         0.9, 0.12);\n"
    "        #ifdef HAS_SHADOW\n"
    "        lowp float illu = illumination(v_mpos);\n"
    "        power *= illu;\n"
    "        #endif\n"
    "\n"
    "        power = max(power, u_min_brightness);\n"
    "        color *= power;\n"
    "\n"
    "        // Earth shadow effect on the moon.\n"
    "        #ifdef HAS_SHADOW\n"
    "        if (u_is_moon == 1 && illu < 0.99) {\n"
    "            vec4 shadow_col = texture2D(u_shadow_color_tex, vec2(illu, 0.5));\n"
    "            color = mix(color, shadow_col.rgb, shadow_col.a);\n"
    "        }\n"
    "        #endif\n"
    "\n"
    "    } else if (u_material == 1) { // basic\n"
    "        float light = max(0.0, dot(n, light_dir));\n"
    "        light = max(light, u_min_brightness);\n"
    "        color *= vec3(light) + u_light_emit;\n"
    "\n"
    "    } else if (u_material == 2) { // ring\n"
    "        lowp float illu = illumination(v_mpos);\n"
    "        illu = max(illu, u_min_brightness);\n"
    "        color *= illu;\n"
    "    }\n"
    "\n"
    "    gl_FragColor = vec4(color, base_color.a);\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_planet_glsl, "shaders/planet.glsl", DATA_shaders_planet_glsl, false)

static const unsigned char DATA_shaders_points_glsl[1361] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "uniform lowp vec4 u_color;\n"
    "\n"
    "// Size of the core point, not including the halo relative to the total\n"
    "// size of the rendered point.\n"
    "// 0 -> only halo (not supported), 1 -> no halo\n"
    "uniform lowp float u_core_size;\n"
    "\n"
    "varying lowp    vec4 v_color;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "attribute lowp    vec4  a_color;\n"
    "attribute mediump float a_size;\n"
    "\n"
    "#ifdef IS_3D\n"
    "    #include \"projections.glsl\"\n"
    "    attribute highp   vec3  a_pos;\n"
    "#else\n"
    "    attribute highp   vec2  a_pos;\n"
    "#endif\n"
    "\n"
    "void main()\n"
    "{\n"
    "    #ifdef IS_3D\n"
    "        gl_Position = proj(a_pos);\n"
    "    #else\n"
    "        gl_Position = vec4(a_pos, 1.0, 1.0);\n"
    "    #endif\n"
    "\n"
    "    gl_PointSize = a_size * 2.0 / u_core_size;\n"
    "    v_color = a_color * u_color;\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "void main()\n"
    "{\n"
    "    mediump float dist;\n"
    "    mediump float k;\n"
    "    dist = 2.0 * distance(gl_PointCoord, vec2(0.5, 0.5));\n"
    "\n"
    "    // Center bright point.\n"
    "    k = smoothstep(u_core_size * 1.25, u_core_size * 0.75, dist);\n"
    "\n"
    "    // Halo\n"
    "    k += smoothstep(1.0, 0.0, dist) * 0.08;\n"
    "    gl_FragColor.rgb = v_color.rgb;\n"
    "    gl_FragColor.a = v_color.a * clamp(k, 0.0, 1.0);\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_points_glsl, "shaders/points.glsl", DATA_shaders_points_glsl, false)

static const unsigned char DATA_shaders_projections_glsl[1831] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "/*\n"
    " * Helper to perform different non linear projection.\n"
    " *\n"
    " * Define one function: vec4 proj(vec3).\n"
    " *\n"
    " * PROJ should be defined with the id of the projection used.\n"
    " */\n"
    "\n"
    "#define PROJ_PERSPECTIVE        1\n"
    "#define PROJ_STEROGRAPHIC       2\n"
    "#define PROJ_MOLLWEIDE          5\n"
    "\n"
    "#ifndef PROJ\n"
    "#error PROJ undefined\n"
    "#endif\n"
    "\n"
    "uniform highp mat4 u_proj_mat;\n"
    "\n"
    "#if (PROJ == PROJ_PERSPECTIVE)\n"
    "highp vec4 proj(highp vec3 pos) {\n"
    "    return u_proj_mat * vec4(pos, 1.0);\n"
    "}\n"
    "#endif\n"
    "\n"
    "#if (PROJ == PROJ_STEROGRAPHIC)\n"
    "\n"
    "highp vec4 proj(highp vec3 pos) {\n"
    "    highp float dist = length(pos);\n"
    "    highp vec3 p = pos / dist;\n"
    "    p.xy /= 0.5 * (1.0 - p.z);\n"
    "    p.z = -1.0;\n"
    "    p *= dist;\n"
    "    return u_proj_mat * vec4(p, 1.0);\n"
    "}\n"
    "\n"
    "#endif\n"
    "\n"
    "#if (PROJ == PROJ_MOLLWEIDE)\n"
    "\n"
    "#define PI 3.14159265\n"
    "#define MAX_ITER 10\n"
    "#define PRECISION 1e-7\n"
    "#define SQRT2 1.4142135623730951\n"
    "\n"
    "highp vec4 proj(highp vec3 v)\n"
    "{\n"
    "    highp float dist = length(v);\n"
    "    highp float phi, lambda, theta, d, k;\n"
    "\n"
    "    lambda = atan(v[0], -v[2]);\n"
    "    phi = atan(v[1], sqrt(v[0] * v[0] + v[2] * v[2]));\n"
    "\n"
    "    k = PI * sin(phi);\n"
    "    theta = phi;\n"
    "    for (int i = 0; i < MAX_ITER; i++) {\n"
    "        d = 2.0 + 2.0 * cos(2.0 * theta);\n"
    "        if (abs(d) < PRECISION) break;\n"
    "        d = (2.0 * theta + sin(2.0 * theta) - k) / d;\n"
    "        theta -= d;\n"
    "        if (abs(d) < PRECISION) break;\n"
    "    }\n"
    "\n"
    "    highp vec3 p;\n"
    "    p.xy = vec2(2.0 * SQRT2 / PI * lambda * cos(theta), SQRT2 * sin(theta));\n"
    "    p.z = -1.0;\n"
    "    p *= dist;\n"
    "    vec4 ret = u_proj_mat * vec4(p, 1.0);\n"
    "    ret.z = 0.0;\n"
    "    ret.w = 1.0;\n"
    "    return ret;\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_projections_glsl, "shaders/projections.glsl", DATA_shaders_projections_glsl, false)

static const unsigned char DATA_shaders_texture_2d_glsl[1210] __attribute__((aligned(4))) =
    "/* Stellarium Web Engine - Copyright (c) 2022 - Stellarium Labs SRL\n"
    " *\n"
    " * This program is licensed under the terms of the GNU AGPL v3, or\n"
    " * alternatively under a commercial licence.\n"
    " *\n"
    " * The terms of the AGPL v3 license can be found in the main directory of this\n"
    " * repository.\n"
    " */\n"
    "\n"
    "uniform mediump vec4        u_color;\n"
    "uniform mediump sampler2D   u_tex;\n"
    "uniform lowp    vec2        u_win_size;\n"
    "\n"
    "varying highp   vec2        v_tex_pos;\n"
    "\n"
    "#ifdef VERTEX_SHADER\n"
    "\n"
    "#ifdef HAS_VIEW_POS\n"
    "    attribute highp vec3 a_pos;\n"
    "    #includes \"projections.glsl\"\n"
    "#endif\n"
    "\n"
    "attribute highp     vec2    a_wpos;\n"
    "attribute mediump   vec2    a_tex_pos;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    #ifdef HAS_VIEW_POS\n"
    "        gl_Position = proj(a_pos);\n"
    "    #else\n"
    "        gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
    "    #endif\n"
    "    gl_Position.xy = (a_wpos / u_win_size - 0.5) * vec2(2.0, -2.0);\n"
    "    gl_Position.xy *= gl_Position.w;\n"
    "    v_tex_pos = a_tex_pos;\n"
    "}\n"
    "\n"
    "#endif\n"
    "#ifdef FRAGMENT_SHADER\n"
    "\n"
    "void main()\n"
    "{\n"
    "#ifndef TEXTURE_LUMINANCE\n"
    "    gl_FragColor = texture2D(u_tex, v_tex_pos) * u_color;\n"
    "#else\n"
    "    // Luminance mode: the texture only applies to the alpha channel.\n"
    "    gl_FragColor = u_color;\n"
    "    gl_FragColor.a *= texture2D(u_tex, v_tex_pos).r;\n"
    "#endif\n"
    "}\n"
    "\n"
    "#endif\n"
    "";

ASSET_REGISTER(shaders_texture_2d_glsl, "shaders/texture_2d.glsl", DATA_shaders_texture_2d_glsl, false)

